package com.clarte.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.TimeZone;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

public class FtpUtil {
	private FTPClient ftpClient;  
	private String strIp;  
	private int intPort;  
	private String user;  
	private String password;  

	private static Logger logger = Logger.getLogger(FtpUtil.class);  

	/* * 
	 * Ftp构造函数 
	 */  
	public FtpUtil(String strIp, int intPort, String user, String Password) {  
	    this.strIp = strIp;  
	    this.intPort = intPort;  
	    this.user = user;  
	    this.password = Password;  
	    this.ftpClient = new FTPClient();  
	}  
	/** 
	 * @return 判断是否登入成功 
	 * */  
	public boolean ftpLogin() {  
	    boolean isLogin = false;  
	    FTPClientConfig ftpClientConfig = new FTPClientConfig();  
	    ftpClientConfig.setServerTimeZoneId(TimeZone.getDefault().getID());  
	    this.ftpClient.setControlEncoding("utf8");  
	    this.ftpClient.configure(ftpClientConfig);  
	    try {  
	        if (this.intPort > 0) {  
	            this.ftpClient.connect(this.strIp, this.intPort);  
	        } else {  
	            this.ftpClient.connect(this.strIp);  
	        }  
	        // FTP服务器连接回答  
	        int reply = this.ftpClient.getReplyCode();  
	        if (!FTPReply.isPositiveCompletion(reply)) {  
	            this.ftpClient.disconnect();  
	            logger.error("登录FTP服务失败！");  
	            return isLogin;  
	        }  
	        isLogin = this.ftpClient.login(this.user, this.password);  
	        // 设置传输协议  
	        this.ftpClient.enterLocalPassiveMode();  
	        this.ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
	    } catch (Exception e) {  
	        e.printStackTrace();  
	        logger.error(this.user + "登录FTP服务失败！" + e.getMessage());  
	    }  
	    this.ftpClient.setBufferSize(1024 * 2);  
	    this.ftpClient.setControlKeepAliveTimeout(300);
	    return isLogin;  
	}  

	/** 
	 * @退出关闭服务器链接 
	 * */  
	public void ftpLogOut() {  
	    if (null != this.ftpClient && this.ftpClient.isConnected()) {  
	        try {  
	            this.ftpClient.logout();// 退出FTP服务器  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	            logger.warn("退出FTP服务器异常！" + e.getMessage());  
	        } finally {  
	            try {  
	                this.ftpClient.disconnect();// 关闭FTP服务器的连接  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	                logger.warn("关闭FTP服务器的连接异常！");  
	            }  
	        }  
	    }  
	}  

	/*** 
	 * 上传Ftp文件 
	  * @param localFile 当地文件 
	  * @param romotUpLoadePath上传服务器路径 - 应该以/结束 
	  * */  
	public boolean uploadFile(File localFile, String romotUpLoadePath) {  
	    BufferedInputStream inStream = null;  
	    boolean success = false;  
	    try {  
	    	if(this.createDir(romotUpLoadePath)){
	    		this.ftpClient.changeWorkingDirectory(romotUpLoadePath);// 改变工作路径  
	    		inStream = new BufferedInputStream(new FileInputStream(localFile));  
	    		success = this.ftpClient.storeFile(localFile.getName(), inStream);  
	    	}
	    } catch (FileNotFoundException e) {  
	        e.printStackTrace();  
	        logger.error(localFile + "未找到");  
	    } catch (IOException e) {  
	        e.printStackTrace();  
	    } finally {  
	        if (inStream != null) {  
	            try {  
	                inStream.close();  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	            }  
	        }  
	    }  
	    return success;  
	}  

	/*** 
	 * 下载文件 
	 * @param remoteFileName   待下载文件名称 
	 * @param localDires 下载到当地那个路径下 
	 * @param remoteDownLoadPath remoteFileName所在的路径 
	 * */  

	public boolean downloadFile(String remoteFileName, String localDires,  
	        String remoteDownLoadPath) {
	    String strFilePath = localDires + remoteFileName;  
	    BufferedOutputStream outStream = null;  
	    boolean success = false;  
	    try {  
	    	new File(localDires).mkdirs();
	        this.ftpClient.changeWorkingDirectory(remoteDownLoadPath);  
	        outStream = new BufferedOutputStream(new FileOutputStream(  
	                strFilePath));  
	        success = this.ftpClient.retrieveFile(remoteFileName, outStream);  
	    } catch (Exception e) {  
	        e.printStackTrace();  
	        logger.error(remoteFileName + "下载失败");  
	    } finally {  
	        if (null != outStream) {  
	            try {  
	                outStream.flush();  
	                outStream.close();  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	            }  
	        }  
	    }  
	    return success;  
	}  

	/*** 
	 * @上传文件夹 
	 * @param localDirectory 
	 *            当地文件夹 
	 * @param remoteDirectoryPath 
	 *            Ftp 服务器路径 以目录"/"结束 
	 * */  
	public boolean uploadDirectory(String localDirectory,  
	        String remoteDirectoryPath) {
	    File src = new File(localDirectory);  
        remoteDirectoryPath = remoteDirectoryPath + src.getName() + "/";  
        if(this.createDir(remoteDirectoryPath)){
        	File[] allFile = src.listFiles();  
        	for (int currentFile = 0; currentFile < allFile.length; currentFile++) {  
        		if (!allFile[currentFile].isDirectory()) {  
        			String srcName = allFile[currentFile].getPath();  
        			uploadFile(new File(srcName), remoteDirectoryPath);  
        		}else{
        			uploadDirectory(allFile[currentFile].getPath(),remoteDirectoryPath);  
        		}
        	}  
        	return true;  
        }else{
        	return false;
        }
	}  

	/*** 
	 * @下载文件夹 
	 * @param localDirectoryPath本地地址 
	 * @param remoteDirectory 远程文件夹 
	 * */  
	public boolean downLoadDirectory(String localDirectoryPath,String remoteDirectory) {  
	    try {  
	        String fileName = new File(remoteDirectory).getName();  
	        localDirectoryPath = localDirectoryPath + fileName + "/";  
	        new File(localDirectoryPath).mkdirs();  
	        FTPFile[] allFile = this.ftpClient.listFiles(remoteDirectory);  
	        for (int currentFile = 0; currentFile < allFile.length; currentFile++) {  
	            if (!allFile[currentFile].isDirectory()) {  
	                downloadFile(allFile[currentFile].getName(),localDirectoryPath, remoteDirectory);  
	            }else{
	            	String strremoteDirectoryPath = remoteDirectory + "/"+ allFile[currentFile].getName();  
	            	downLoadDirectory(localDirectoryPath,strremoteDirectoryPath);  
	            }
	        }  
	    } catch (IOException e) {  
	        e.printStackTrace();  
	        logger.error("下载文件夹失败");  
	        return false;  
	    }  
	    return true;  
	}  
	private boolean createDir(String remote){
		if(remote.equals("/")||remote.equals("")){
			return true;
		}else{
			remote = remote.startsWith("/")?remote:"/"+remote;
			remote = remote.endsWith("/")?remote:remote+"/";
		}
		boolean success = true;
        try {
			// 如果远程目录不存在，则递归创建远程服务器目录
			int start = 1;
		    int end = remote.indexOf("/", start);
		    while (true) {
		        String subDirectory = remote.substring(start, end);
		        if (!ftpClient.changeWorkingDirectory(subDirectory)) {
		            if (ftpClient.makeDirectory(subDirectory)) {
		            	ftpClient.changeWorkingDirectory(subDirectory);
		            } else {
		                logger.error("创建目录失败");
		                success = false;
		                break;
		            }
		        }
		        start = end + 1;
		        end = remote.indexOf("/", start);
		        // 检查所有目录是否创建完毕
		        if (end <= start) {
		            break;
		        }
		    }
		} catch (IOException e) {
			e.printStackTrace();
			success = false;
		}
        return success;
	}
	  
	public static void main(String[] args) throws IOException {  
	    FtpUtil ftp=new FtpUtil("10.211.91.77",6621,"chenc","chenc");  
	    ftp.ftpLogin();  
	    //上传文件夹  
	    ftp.uploadFile(new File("d:\\edit1.csv"), "/wwq/wwq/");
	    //下载文件夹  
//	    ftp.downLoadDirectory("d://tmp//", "/home/data/DataProtemp");  
	    ftp.ftpLogOut();          
	}
}
